package io.plus.user_interface.io.common.message;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import drds.common.$;
import io.plus.user_interface.io.common.Constants;
import io.plus.user_interface.io.common.UserConfiguration;
import io.plus.user_interface.io.common.listener.BindGroupListener;
import io.plus.user_interface.io.common.listener.BindGroupListenerImpl;
import io.plus.user_interface.io.common.packet.ChatMessage;
import io.plus.user_interface.io.common.packet.Group;
import io.plus.user_interface.io.common.packet.User;
import io.plus.user_interface.io.common.packet.UserMessage;
import io.plus.user_interface.io.common.utils.ChatKit;
import io.plus.user_interface.io.common.utils.JsonKit;
import io.plus.user_interface.redis.CacheImpl;
import io.plus.user_interface.redis.CacheManager;
import io.plus.user_interface.redis.JedisTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

//import org.apache.commons.collections4.CollectionUtils;
//import org.apache.commons.lang3.StringUtils;

/**
 * Redis获取持久化+同步消息助手;
 */

public class RedisMessageHelper implements MessageHelper, Constants {
    static {
        CacheManager.register(user, Integer.MAX_VALUE, Integer.MAX_VALUE);
        CacheManager.register(group, Integer.MAX_VALUE, Integer.MAX_VALUE);
        CacheManager.register(store, Integer.MAX_VALUE, Integer.MAX_VALUE);
        CacheManager.register(push, Integer.MAX_VALUE, Integer.MAX_VALUE);
    }

    private final String SUBFIX = ":";
    protected UserConfiguration userConfiguration;
    private CacheImpl groupCacheImpl = null;
    private CacheImpl pushCacheImpl = null;
    private CacheImpl storeCacheImpl = null;
    private CacheImpl userCacheImpl = null;
    private Logger log = LoggerFactory.getLogger(RedisMessageHelper.class);

    public RedisMessageHelper() {
        this(null);
    }

    public RedisMessageHelper(UserConfiguration userConfiguration) {
        this.groupCacheImpl = CacheManager.getCache(group);
        this.pushCacheImpl = CacheManager.getCache(push);
        this.storeCacheImpl = CacheManager.getCache(store);
        this.userCacheImpl = CacheManager.getCache(user);
        this.userConfiguration = userConfiguration;
    }

    public UserConfiguration getUserConfiguration() {
        return userConfiguration;
    }

    public void setUserConfiguration(UserConfiguration userConfiguration) {
        this.userConfiguration = userConfiguration;
    }

    @Override
    public void addGroupUser(String userId, String groupId) {
        List<String> userIdList = groupCacheImpl.listGetAll(groupId);
        if (!userIdList.contains(userId)) {
            groupCacheImpl.listPushTail(groupId, userId);
        }
    }

    /**
     * 获取好友分组所有成员信息
     *
     * @param userId
     * @param type(0:所有在线用户,1:所有离线用户,2:所有用户[在线+离线])
     * @return
     */
    @Override
    public List<Group> getAllFriendUsers(String userId, Integer type) {
        if (userId == null) {
            return null;
        }
        List<JSONObject> friendJSONObjectList = userCacheImpl.get(userId + SUBFIX + FRIENDS, List.class);
        if ($.isNotNullAndHasElement(friendJSONObjectList)) {
            return null;
        }
        List<Group> friends = new ArrayList<Group>();
        for (JSONObject friendJSONObject : friendJSONObjectList) {
            Group group = JSON.toJavaObject(friendJSONObject, Group.class);
            List<User> userList = group.getUsers();
            if ($.isNotNullAndHasElement(userList)) {
                continue;
            }
            List<User> userResults = new ArrayList<User>();
            for (User user : userList) {
                setUserStatus(user);
                String status = user.getStatus();
                if (type == 0 && ONLINE.equals(status)) {
                    userResults.add(user);
                } else if (type == 1 && OFFLINE.equals(status)) {
                    userResults.add(user);
                } else if (type == 2) {
                    userResults.add(user);
                }
            }
            group.setUsers(userResults);
            friends.add(group);
        }
        return friends;
    }

    /**
     * 获取群组所有成员信息（在线+离线)
     *
     * @param userId
     * @param type(0:所有在线用户,1:所有离线用户,2:所有用户[在线+离线])
     * @return
     */
    @Override
    public List<Group> getAllGroupUsers(String userId, Integer type) {
        if (userId == null) {
            return null;
        }
        List<String> groupIdList = userCacheImpl.listGetAll(userId + SUBFIX + group);
        if ($.isNotNullAndHasElement(groupIdList)) {
            return null;
        }
        List<Group> groupList = new ArrayList<Group>();
        for (String groupId : groupIdList) {
            Group group = getGroupUsers(groupId, type);
            if (group != null) {
                groupList.add(group);
            }
        }
        return groupList;
    }


    @Override
    public BindGroupListener getBindListener() {

        return new BindGroupListenerImpl(userConfiguration);
    }


    @Override
    public UserMessage getFriendHistoryMessage(String userid, String from_userid, Double beginTime, Double endTime, Integer offset, Integer count) {
        String sessionId = ChatKit.sessionId(userid, from_userid);
        List<String> messages = null;
        String key = user + SUBFIX + sessionId;
        boolean isTimeBetween = (beginTime != null && endTime != null);
        boolean isPage = (offset != null && count != null);
        //消息区间，不分页
        if (isTimeBetween && !isPage) {
            messages = storeCacheImpl.sortSetGetAll(key, beginTime, endTime);
            //消息区间，并且分页;
        } else if (isTimeBetween && isPage) {
            messages = storeCacheImpl.sortSetGetAll(key, beginTime, endTime, offset, count);
            //所有消息，并且分页;
        } else if (!isTimeBetween && isPage) {
            messages = storeCacheImpl.sortSetGetAll(key, 0, Double.MAX_VALUE, offset, count);
            //所有消息，不分页;
        } else {
            messages = storeCacheImpl.sortSetGetAll(key);
        }
        if ($.isNotNullAndHasElement(messages)) {
            return null;
        }
        UserMessage messageData = new UserMessage(userid);
        putFriendsHistoryMessage(messageData, JsonKit.toArray(messages, ChatMessage.class), from_userid);
        return messageData;
    }

    @Override
    public UserMessage getFriendsOfflineMessage(String userid) {
        try {
            Set<String> keySet = JedisTemplate.me().keys(push + SUBFIX + user + SUBFIX + userid);
            UserMessage userMessage = new UserMessage(userid);
            if (keySet != null && keySet.size() > 0) {
                List<ChatMessage> results = new ArrayList<ChatMessage>();
                Iterator<String> iterator = keySet.iterator();
                //获取好友离线消息;
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    key = key.substring(key.indexOf(user + SUBFIX));
                    List<String> messages = pushCacheImpl.sortSetGetAll(key);
                    pushCacheImpl.remove(key);
                    results.addAll(JsonKit.toArray(messages, ChatMessage.class));
                }
                putFriendsMessage(userMessage, results);
            }
            List<String> groups = userCacheImpl.listGetAll(userid + SUBFIX + group);
            //获取群组离线消息;
            if (groups != null) {
                for (String groupid : groups) {
                    UserMessage groupMessageData = getGroupOfflineMessage(userid, groupid);
                    if (groupMessageData != null) {
                        putGroupMessage(userMessage, groupMessageData.getGroups().get(groupid));
                    }
                }
            }
            return userMessage;
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return null;
    }

    @Override
    public UserMessage getFriendsOfflineMessage(String userid, String from_userid) {
        String key = user + SUBFIX + userid + SUBFIX + from_userid;
        List<String> messageList = pushCacheImpl.sortSetGetAll(key);
        List<ChatMessage> datas = JsonKit.toArray(messageList, ChatMessage.class);
        pushCacheImpl.remove(key);
        return putFriendsMessage(new UserMessage(userid), datas);
    }

    /**
     * 获取好友分组所有成员信息
     *
     * @param user_id
     * @param friend_group_id
     * @param type(0:所有在线用户,1:所有离线用户,2:所有用户[在线+离线])
     * @return
     */

    @Override
    public Group getFriendUsers(String user_id, String friend_group_id, Integer type) {
        if (user_id == null || friend_group_id == null || type == null) {
            return null;
        }
        List<Group> friends = userCacheImpl.get(user_id + SUBFIX + FRIENDS, List.class);
        if (friends == null || friends.isEmpty()) {
            return null;
        }
        for (Group group : friends) {
            if (friend_group_id.equals(group.getId())) {
                List<User> users = group.getUsers();
                if ($.isNotNullAndHasElement(users)) {
                    return null;
                }
                List<User> userResults = new ArrayList<User>();
                for (User user : users) {
                    setUserStatus(user);
                    String status = user.getStatus();
                    if (type == 0 && ONLINE.equals(status)) {
                        userResults.add(user);
                    } else if (type == 1 && OFFLINE.equals(status)) {
                        userResults.add(user);
                    } else {
                        userResults.add(user);
                    }
                }
                group.setUsers(userResults);
                return group;
            }
        }
        return null;
    }

    @Override
    public UserMessage getGroupHistoryMessage(String userid, String groupid, Double beginTime, Double endTime, Integer offset, Integer count) {
        String key = group + SUBFIX + groupid;
        List<String> messages = null;
        boolean isTimeBetween = (beginTime != null && endTime != null);
        boolean isPage = (offset != null && count != null);
        //消息区间，不分页
        if (isTimeBetween && !isPage) {
            messages = storeCacheImpl.sortSetGetAll(key, beginTime, endTime);
            //消息区间，并且分页;
        } else if (isTimeBetween && isPage) {
            messages = storeCacheImpl.sortSetGetAll(key, beginTime, endTime, offset, count);
            //所有消息，并且分页;
        } else if (!isTimeBetween && isPage) {
            messages = storeCacheImpl.sortSetGetAll(key, 0, Double.MAX_VALUE, offset, count);
            //所有消息，不分页;
        } else {
            messages = storeCacheImpl.sortSetGetAll(key);
        }
        if ($.isNotNullAndHasElement(messages)) {
            return null;
        }
        UserMessage messageData = new UserMessage(userid);
        putGroupMessage(messageData, JsonKit.toArray(messages, ChatMessage.class));
        return messageData;
    }

    @Override
    public UserMessage getGroupOfflineMessage(String userid, String groupid) {
        String key = group + SUBFIX + groupid + SUBFIX + userid;
        List<String> messages = pushCacheImpl.sortSetGetAll(key);
        if ($.isNotNullAndHasElement(messages)) {
            return null;
        }
        UserMessage messageData = new UserMessage(userid);
        putGroupMessage(messageData, JsonKit.toArray(messages, ChatMessage.class));
        pushCacheImpl.remove(key);
        return messageData;
    }

    /**
     * 获取用户拥有的群组;
     *
     * @param user_id
     * @return
     */
    @Override
    public List<String> getGroups(String user_id) {
        List<String> groups = userCacheImpl.listGetAll(user_id + SUBFIX + group);
        return groups;
    }

    @Override
    public List<String> getGroupUsers(String group_id) {
        String group_user_key = group_id + SUBFIX + user;
        List<String> users = groupCacheImpl.listGetAll(group_user_key);
        return users;
    }

    /**
     * 获取群组所有成员信息
     *
     * @param group_id
     * @param type(0:所有在线用户,1:所有离线用户,2:所有用户[在线+离线])
     * @return
     */
    @Override
    public Group getGroupUsers(String group_id, Integer type) {
        if (group_id == null || type == null) {
            return null;
        }
        Group group = groupCacheImpl.get(group_id + SUBFIX + INFO, Group.class);
        if (group == null) {
            return null;
        }
        List<String> userIds = this.getGroupUsers(group_id);
        if ($.isNotNullAndHasElement(userIds)) {
            return null;
        }
        List<User> users = new ArrayList<User>();
        for (String userId : userIds) {
            User user = getUserByType(userId, type);
            if (user != null) {
                String status = user.getStatus();
                if (type == 0 && ONLINE.equals(status)) {
                    users.add(user);
                } else if (type == 1 && OFFLINE.equals(status)) {
                    users.add(user);
                } else if (type == 2) {
                    users.add(user);
                }
            }
        }
        group.setUsers(users);
        return group;
    }

    /**
     * 根据在线类型获取用户信息;
     *
     * @param userid
     * @param type
     * @return
     */
    @Override
    public User getUserByType(String userid, Integer type) {
        User user = userCacheImpl.get(userid + SUBFIX + INFO, User.class);
        if (user == null) {
            return null;
        }
        boolean isOnline = this.isOnline(userid);
        String status = isOnline ? ONLINE : OFFLINE;
        if (type == 0 || type == 1) {
            if (type == 0 && isOnline) {
                user.setStatus(status);
            } else if (type == 1 && !isOnline) {
                user.setStatus(status);
            }
        } else if (type == 2) {
            user.setStatus(status);
        }
        return user;
    }

    /**
     * 初始化用户在线状态;
     *
     * @param user
     */
    public void setUserStatus(User user) {
        if (user == null) {
            return;
        }
        String userId = user.getId();
        boolean isOnline = this.isOnline(userId);
        if (isOnline) {
            user.setStatus(ONLINE);
        } else {
            user.setStatus(OFFLINE);
        }
    }

    @Override
    public boolean isOnline(String userid) {
        try {
            Set<String> keySet = JedisTemplate.me().keys(user + SUBFIX + userid + SUBFIX + TERMINAL);
            if (keySet != null && keySet.size() > 0) {
                Iterator<String> iterator = keySet.iterator();
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    key = key.substring(key.indexOf(userid));
                    String isOnline = userCacheImpl.get(key, String.class);
                    if (ONLINE.equals(isOnline)) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return false;
    }

    /**
     * 放入用户好友历史消息;
     *
     * @param userMessage
     * @param messages
     */
    public UserMessage putFriendsHistoryMessage(UserMessage userMessage,//
                                                List<ChatMessage> messages, String friendId) {
        if (userMessage == null || messages == null) {
            return null;
        }
        for (ChatMessage chatBody : messages) {
            String fromUserId = chatBody.getFrom();
            if ($.isNullOrEmpty(fromUserId)) {
                continue;
            }
            List<ChatMessage> friendMessages = userMessage.getFriends().get(friendId);
            if (friendMessages == null) {
                friendMessages = new ArrayList<ChatMessage>();
                userMessage.getFriends().put(friendId, friendMessages);
            }
            friendMessages.add(chatBody);
        }
        return userMessage;
    }

    /**
     * 放入用户好友消息;
     *
     * @param userMessage
     * @param chatMessageList
     */
    public UserMessage putFriendsMessage(UserMessage userMessage, List<ChatMessage> chatMessageList) {
        if (userMessage == null || chatMessageList == null) {
            return null;
        }
        for (ChatMessage chatMessage : chatMessageList) {
            String fromUserId = chatMessage.getFrom();
            if ($.isNullOrEmpty(fromUserId)) {
                continue;
            }
            List<ChatMessage> friendMessages = userMessage.getFriends().get(fromUserId);
            if (friendMessages == null) {
                friendMessages = new ArrayList<ChatMessage>();
                userMessage.getFriends().put(fromUserId, friendMessages);
            }
            friendMessages.add(chatMessage);
        }
        return userMessage;
    }

    /**
     * 放入用户群组消息;
     */
    public UserMessage putGroupMessage(UserMessage userMessage, List<ChatMessage> chatMessageList) {
        if (userMessage == null || chatMessageList == null) {
            return null;
        }
        for (ChatMessage chatMessage : chatMessageList) {
            String groupId = chatMessage.getGroupId();
            if ($.isNullOrEmpty(groupId)) {
                continue;
            }
            List<ChatMessage> groupChatMessageList = userMessage.getGroups().get(groupId);
            if (groupChatMessageList == null) {
                groupChatMessageList = new ArrayList<ChatMessage>();
                userMessage.getGroups().put(groupId, groupChatMessageList);
            }
            groupChatMessageList.add(chatMessage);
        }
        return userMessage;
    }

    @Override
    public void removeGroupUser(String userId, String groupId) {
        groupCacheImpl.listRemove(groupId, userId);
    }

    @Override
    public void writeMessage(String timelineTable, String timelineId, ChatMessage chatBody) {
        double score = chatBody.getCreateTime();
        CacheManager.getCache(timelineTable).sortSetPush(timelineId, score, chatBody);
    }
}
